# ==============================================================================
# Makefile helper functions for docker image
#

define DOCKERFILE_TPL
FROM BUILDER_IMAGE AS builder

LABEL stage=gobuilder
LABEL maintainer="<MAINTAINER>"

ENV GO111MODULE=on \
  GOPROXY=https://goproxy.cn \
  CGO_ENABLED=0 \
  GOOS=linux \
  GOARCH=amd64

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \
  && apk update --no-cache && apk add --no-cache tzdata

WORKDIR /build

COPY go.mod go.mod
COPY go.sum go.sum
RUN go mod download

COPY api api
COPY app/APP_NAME app/APP_NAME
COPY pkg pkg

RUN go build -o APP_NAME ./app/APP_NAME/cmd/*

FROM BASE_IMAGE

COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai

WORKDIR /app

COPY --from=builder /build/APP_NAME .
COPY --from=builder /build/app/APP_NAME/configs ./configs

EXPOSE 8080

VOLUME /data/conf

CMD ["./APP_NAME", "-conf", "configs/config.yaml"]
endef
export DOCKERFILE_TPL

DOCKER := docker
DOCKER_SUPPORTED_API_VERSION ?= 1.32

REGISTRY_PREFIX ?= will0523

BUILDER_IMAGE = golang:1.19.1-alpine3.16
BASE_IMAGE = alpine:3.16
MAINTAINER = 1003097699@qq.com

# EXTRA_ARGS ?= --no-cache --pull
EXTRA_ARGS ?=
_DOCKER_BUILD_EXTRA_ARGS :=

ifdef HTTP_PROXY
_DOCKER_BUILD_EXTRA_ARGS += --build-arg HTTP_PROXY=${HTTP_PROXY}
endif

ifneq ($(EXTRA_ARGS), )
_DOCKER_BUILD_EXTRA_ARGS += $(EXTRA_ARGS)
endif

# Determine image files by looking into build/docker/*/Dockerfile
IMAGES_DIR ?= $(wildcard ${ROOT_DIR}/app/*)
# Determine images names by stripping out the dir names
IMAGES ?= $(filter-out tools,$(foreach image,${IMAGES_DIR},$(notdir ${image})))

ifeq (${IMAGES},)
  $(error Could not determine IMAGES, set ROOT_DIR or run in source dir)
endif

.PHONY: image.verify
image.verify:
	$(eval API_VERSION := $(shell $(DOCKER) version | grep -E 'API version: {1,6}[0-9]' | head -n1 | awk '{print $$3} END { if (NR==0) print 0}' ))
	$(eval PASS := $(shell echo "$(API_VERSION) > $(DOCKER_SUPPORTED_API_VERSION)" | bc))
	@if [ $(PASS) -ne 1 ]; then \
		$(DOCKER) -v ;\
		echo "Unsupported docker version. Docker API version should be greater than $(DOCKER_SUPPORTED_API_VERSION)"; \
		exit 1; \
	fi

.PHONY: image.daemon.verify
image.daemon.verify:
	$(eval PASS := $(shell $(DOCKER) version | grep -q -E 'Experimental: {1,6}true' && echo 1 || echo 0))
	@if [ $(PASS) -ne 1 ]; then \
		echo "Experimental features of Docker daemon is not enabled. Please add \"experimental\": true in '/etc/docker/daemon.json' and then restart Docker daemon."; \
		exit 1; \
	fi

.PHONY: image.build
image.build: image.verify go.build.verify $(addprefix image.build., $(IMAGES))

.PHONY: image.build.%
image.build.%: image.gen.%
	$(eval IMAGE := $*)
	@echo "===========> Building docker image $(IMAGE):$(VERSION) for $(IMAGE_PLAT)"
	$(eval BUILD_SUFFIX :=  -f $(ROOT_DIR)/app/$(IMAGE)/Dockerfile .)
	$(DOCKER) build $(_DOCKER_BUILD_EXTRA_ARGS) -t $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) $(BUILD_SUFFIX)

.PHONY: image.gen
image.gen: image.verify $(addprefix image.gen., $(IMAGES))

.PHONY: image.gen.%
image.gen.%:
	$(eval IMAGE := $*)
	@echo "===========> Generate dockerfile $(IMAGE):$(VERSION)"
	@echo "$$DOCKERFILE_TPL" \
		| sed "s#BUILDER_IMAGE#$(BUILDER_IMAGE)#g" \
		| sed "s#BASE_IMAGE#$(BASE_IMAGE)#g" \
		| sed "s#MAINTAINER#$(MAINTAINER)#g" \
		| sed "s#APP_NAME#$(IMAGE)#g" \
		>$(ROOT_DIR)/app/$(IMAGE)/Dockerfile

.PHONY: image.push
image.push: image.verify go.build.verify $(addprefix image.push., $(IMAGES))

.PHONY: image.push.%
image.push.%:
	$(eval IMAGE := $*)
	$(DOCKER) push $(REGISTRY_PREFIX)/$(IMAGE):$(VERSION) ;

.PHONY: echo.image
echo.image:
	@echo "IMAGES_DIR: $(IMAGES_DIR)"
	@echo "IMAGES: $(IMAGES)"
	@echo "IMAGE: $(addprefix image.gen., $(IMAGES))"